package com.linsen.core.web.config;

import com.linsen.core.common.annotation.AutoConfiguration;
import com.linsen.core.common.convert.factory.StringToEnumConverterFactory;
import com.linsen.core.web.aspect.RequestAccessLogAspect;
import com.linsen.core.web.aspect.RequestLocalAspect;
import com.linsen.core.web.aspect.RequestValidAspect;
import com.linsen.core.web.filter.XssFilter;
import com.linsen.core.web.handler.RequestExceptionHandler;
import com.linsen.core.web.interceptor.RequestInterceptor;
import com.linsen.core.web.props.LinsenWebProperties;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.format.FormatterRegistry;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * @author zhaoyong
 * @date 2023/3/10
 */
@Slf4j
@AutoConfiguration
@RequiredArgsConstructor
@EnableConfigurationProperties({LinsenWebProperties.class})
public class LinsenWebAutoConfiguration implements WebMvcConfigurer {
    private final LinsenWebProperties webProperties;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new RequestInterceptor()).addPathPatterns("/**");
    }

    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addConverterFactory(new StringToEnumConverterFactory());
    }

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        if (this.webProperties.getRequestCors()) {
            registry.addMapping("/**").allowedOriginPatterns("*")
                    .allowedMethods("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS")
                    .allowCredentials(true).maxAge(3600L);
        }
    }

    @Bean
    @ConditionalOnProperty(prefix = "linsen.web", name = "request-xss", havingValue = "true")
    public XssFilter xssFilter() {
        return new XssFilter();
    }

    @Bean
    public RequestExceptionHandler webExceptionHandler(LinsenWebProperties webProperties) {
        return new RequestExceptionHandler(webProperties);
    }

    @Bean
    public RequestAccessLogAspect requestAccessLogAspect(LinsenWebProperties webProperties) {
        return new RequestAccessLogAspect(webProperties);
    }

    // @Bean
    public RequestValidAspect requestValidAspect() {
        return new RequestValidAspect();
    }

    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

    @Bean
    public RequestLocalAspect requestLocalAspect() {
        return new RequestLocalAspect();
    }
}
